package com.utils;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.decodeUtil.DesUtil;
import com.show.api.util.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import static com.utils.ChatClient.getSerialNumber;

/**
 * 将Log日志写入文件中
 * <p>
 * 使用单例模式是因为要初始化文件存放位置
 * <p>
 * Created by waka on 2017/7/21.
 */
public class LogToFile {

    private static String TAG = "<<<<<mobile>>>>>:  ";

    /**
     * SD卡的路径
     **/
    private static String SDPATH = "/sdcard/yzflog/";

    private static boolean LOGO = true;//日志开关

    private static String logPath = null;//log日志存放路径

    private static SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyyMMddHH", Locale.US);//日期格式;
    private static SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyyMMdd", Locale.US);//日期格式;
    private static SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm:ss", Locale.US);//日期格式;

    private static Date date = new Date();//因为log日志是使用日期命名的，使用静态成员变量主要是为了在整个程序运行期间只存在一个.log文件中;
    static DesUtil desUtil;

    /**
     * 初始化，须在使用之前设置，最好在Application创建时调用
     *
     * @param context
     */
    public static void init(Context context, int port1) {
        //logPath = getFilePath(context) + "/Logs";//获得文件储存路径,在后面加"/Logs"建立子文件夹
        String bankname = getPayName(port1);
        logPath = SDPATH + "mobile";//获得文件储存路径,在后面加"/Logs"建立子文件夹
        //初始化加密工具
        desUtil = new DesUtil();
        //删除脚本日志文件
        deleteDir(logPath);
    }

    /**
     * 获得文件存储路径
     *
     * @return
     */
    private static String getFilePath(Context context) {

        if (Environment.MEDIA_MOUNTED.equals(Environment.MEDIA_MOUNTED) || !Environment.isExternalStorageRemovable()) {//如果外部储存可用
            return context.getExternalFilesDir(null).getPath();//获得外部存储路径,默认路径为 /storage/emulated/0/Android/data/com.waka
            // .workspace.logtofile/files/Logs/log_2016-03-14_16-15-09.log
        } else {
            return context.getFilesDir().getPath();//直接存在/data/data里，非root手机是看不到的
        }
    }

    private static final char VERBOSE = 'v';

    private static final char DEBUG = 'd';

    private static final char INFO = 'i';

    private static final char WARN = 'w';

    private static final char ERROR = 'e';

    public static void v(String tag, String msg) {
        if (LOGO) {
            writeToFile(VERBOSE, tag, msg);
        }
    }

    public static void d(String tag, String msg) {
        if (LOGO) {
            writeToFile(DEBUG, tag, msg);
        }
    }

    public static void showLog(String tag, String msg) {
        if (LOGO) {
            writeToFile(WARN, "****" + tag + "****", "====****《" + msg + "》****===");
        }
    }


    public static void i(String tag, String msg) {
        if (LOGO) {
            writeToFile(INFO, tag, msg);
        }
    }

    public static void w(String tag, String msg) {
        if (LOGO) {
            writeToFile(WARN, tag, msg);
        }
    }

    public static void e(String tag, String msg) {
        if (LOGO) {
            writeToFile(ERROR, tag, msg);
        }
    }

    /**
     * 得到调用方法名
     *
     * @return
     */
    public static String getMethodName() {
        Exception exception = new Exception();
        StackTraceElement[] trace = exception.getStackTrace();
        String methodName = trace[1].getMethodName();
        return methodName;
    }

    /**
     * 获取父类方法名
     *
     * @return
     */
    public static String getFatherMethodName() {
        Exception exception = new Exception();
        StackTraceElement[] trace = exception.getStackTrace();
        String methodName = trace[2].getMethodName();
        return methodName;
    }

    /**
     * 将log信息写入文件中
     * <YZF>?{"header":"P_sendBankLoginInfo_M","userName":"18829511857","pwd":"HX315536","bankpwd":"315536","usbPayPwd":"315536","UsbPayEncode":"",
     * "AppKey":"23761498","AppSecret":"2c6651131be1ffc6f6abcb0de6cdc920","AppCode":"e01bc4fae0d84357af843dd0afbef8d2","YyAppid":"52538",
     * "YySecret":"e99a829546784d09a05ab30d3a27ef84","JhAppKey":"f38b7442736cb7b18ea2ec948264dbbe","DmtAppid":"2323232",
     * "DmtSoftkey
     * ":"1111111111","DmtUsername":"2323","DmtUserpwd":"322","UseType":"1","bankId":"14"}</YZF>
     *
     * @param type
     * @param tag
     * @param msg
     */
    private static void writeToFile(char type, String tag, String msg) {
        //        Log.d(TAG, msg);
        if (null == logPath) {
            Log.e(TAG, "logPath == null ，未初始化LogToFile");
            return;
        }

        String fileName = logPath + "/" + getSerialNumber() + "_" + dateFormat2.format(new Date()) + "_M" + ".log";//log日志名，使用时间命名，保证不重复
        // String log = dateFormat.format(date) + " " + type + " " + tag + " " + msg + "\n";//log日志内容，可以自行定制
        String log = dateFormat.format(new Date()) + " " + tag + " : " + msg;
        //                + "\n";//log日志内容，可以自行定制
        log = log.replaceAll("\"", "");
        Log.w("============>", log);
        //如果父路径不存在
        File file = new File(logPath);
        if (!file.exists()) {
            file.mkdirs();//创建父路径
        }

        FileOutputStream fos = null;//FileOutputStream会自动调用底层的close()方法，不用关闭
        BufferedWriter bw = null;
        try {
            fos = new FileOutputStream(fileName, true);//这里的第二个参数代表追加还是覆盖，true为追加，flase为覆盖
            bw = new BufferedWriter(new OutputStreamWriter(fos, Charset.forName("gbk")));
            if (log.contains("P_sendBankLoginInfo_M") && log.contains("pwd")) {
                String[] s = log.split("userName");
                log = s[0] + "username" + s[1].substring(0, 4) + "****" + s[1].substring(9, s[1].length());
                String[] s1 = log.split("pwd");
                String[] s2 = log.split("UsbPayEncode");
                log = s1[0] + "pwd:********,bankpwd:******,usbPayPwd:******,UsbPayEncode" + s2[1];
            }
            //{header:P_sendTrade_M,devices:4bca999c,order:TK1588040651541499,userName:王冰川,bankName:平安银行,bankNo:6230580000094250185,money:0.78,
            // purpose:,type:1,openingBank:null}
            if (log.contains("P_sendTrade_M") || log.contains("C_confirmTrade_S")) {
                String[] s1 = log.split("userName");
                String[] s2 = (s1[1].split(","));
                String s3 = s2[0].split(":")[1];
                String name = s3.substring(s3.length() - 1, s3.length());
                String[] bankNames = log.split("bankName");
                log = s1[0] + "userName:*" + name + ",bankName" + bankNames[1];
                String[] b1 = log.split("bankNo");
                String[] b2 = b1[1].split(":");
                String b3 = b2[1].substring(0, 6);
                String[] b4 = b1[1].split(",");
                String b5 = b4[0].substring(b4[0].length() - 4, b4[0].length());
                String[] moneys = log.split("money");
                log = b1[0] + "bankNo:" + b3 + "*********" + b5 + ",money" + moneys[1];
            }
            //<YZF>{'header':'S_getSMSCode_C','username':'17778971650','bankId':'15'}</YZF>
            if (log.contains("S_getSMSCode_C") && log.contains("username")) {
                String[] s1 = log.split("username");
                log = s1[0] + "username" + s1[1].substring(0, 6) + "****" + s1[1].substring(10, s1[1].length());
            }
            //"{header:C_sendSMSCode_S,smscode:988220,telephone:17778971650}";
            if (log.contains("C_sendSMSCode_S")) {
                String[] s1 = log.split("telephone");
                if (s1[1].length() > 4) {
                    log = s1[0] + "telephone" + s1[1].substring(0, 4) + "****" + s1[1].substring(8, s1[1].length());
                }
            }
//            log = DesUtil.encode(log);
            bw.write(log + "\n");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (bw != null) {
                    bw.close();//关闭缓冲流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //删除文件夹和文件夹里面的文件
    public static void deleteDir(final String pPath) {
        File dir = new File(pPath);
        deleteDirWihtFile(dir);
    }

    /**
     * 删除超过一个月的文件
     *
     * @param dir
     */
    public static void deleteDirWihtFile(File dir) {
        if (dir == null || !dir.exists() || !dir.isDirectory()) {
            return;
        } else {
            File[] files = dir.listFiles();
            if (files.length > 0) {
                /*******获取三十天前时间戳********/
                Calendar now = Calendar.getInstance();
                now.add(Calendar.DAY_OF_MONTH, -30);
                long oldTime = now.getTimeInMillis();
                for (File f : files) {
                    String path = f.toString();
                    String[] split = path.split("_");
                    if (!StringUtils.isEmpty(split[1])) {
                        String date = split[1].replaceAll(".log", "");
                        date += "000000";
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                        String timeStamp = stampToDate(date, sdf);
                        long fileTime = Long.valueOf(timeStamp + "000");
                        if (fileTime < oldTime) {
                            if (f.isFile()) {
                                showLog("银行", "删除---" + path);
                                f.delete();
                            }
                        }
                    }
                }
            }
        }
    }

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(String date_str, SimpleDateFormat format) {

        try {
            return String.valueOf(format.parse(date_str).getTime() / 1000);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return "";
    }


    public static String getPayName(int prot) {
        String temp = "";
        switch (prot) {
            case 6169:
                temp = "北京银行";
                break;
            case 5566:
                temp = "中国银行";
                break;
            case 5588:
                temp = "工商银行";
                break;
            case 5528:
                temp = "浦发银行";
                break;
            case 5568:
                temp = "民生银行";
                break;
            case 5580:
                temp = "邮政银行";
                break;
            case 5533:
                temp = "建设银行";
                break;
            case 5561:
                temp = "兴业银行";
                break;
            case 5599:
                temp = "农业银行";
                break;
            case 5559:
                temp = "交通银行";
                break;
            case 5555:
                temp = "招商银行";
                break;
            case 5558:
                temp = "中信银行";
                break;
            case 5595:
                temp = "光大银行";
                break;
            case 5577:
                temp = "华夏银行";
                break;
        }
        return temp;
    }

    /**
     * 读取SD卡中文本文件
     *
     * @return
     */
    public static String readSDFile(String sdpath) {
        StringBuffer sb = new StringBuffer();
        File file = new File(sdpath);
        try {
            FileInputStream fis = new FileInputStream(file);
            int c;
            while ((c = fis.read()) != -1) {
                sb.append((char) c);
            }
            fis.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }
}